package ui.timeline;

import java.awt.event.MouseEvent;

import javax.swing.JSlider;
import javax.swing.plaf.basic.BasicSliderUI.TrackListener;



/**
 * Listener to handle mouse movements in the slider track.
 */
public class ThreeThumbTimeLineRangeTrackListener extends TrackListener {
    
    /**
	 * 
	 */
	private ThreeThumbTimeLineSliderUI timeLineSliderUI;

	/**
	 * @param timeLineSliderUI
	 */
	
	public ThreeThumbTimeLineRangeTrackListener(ThreeThumbTimeLineSliderUI sliderUI)
	{
		sliderUI.super();
		this.timeLineSliderUI = sliderUI;
	}

	@Override
    public void mousePressed(MouseEvent e) {
        if (!this.timeLineSliderUI.getSlider().isEnabled()) {
            return;
        }

        currentMouseX = e.getX();
        currentMouseY = e.getY();

        if (this.timeLineSliderUI.getSlider().isRequestFocusEnabled()) {
            this.timeLineSliderUI.getSlider().requestFocus();
        }
        
        // Determine which thumb is pressed.  If the upper thumb is 
        // selected (last one dragged), then check its position first;
        // otherwise check the position of the lower thumb first.
        boolean lowerPressed = false;
        boolean upperPressed = false;
        boolean currentPressed = false;
        
        if (this.timeLineSliderUI.isUpperThumbSelected()) 
        {
            if (this.timeLineSliderUI.getUpperThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                upperPressed = true;
            } 
            else if (this.timeLineSliderUI.getLowerThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                lowerPressed = true;
            }
            else if (this.timeLineSliderUI.getThumbRect().contains(currentMouseX, currentMouseY))
        	{
            	currentPressed = true;
        	}
        } 
        else if ( this.timeLineSliderUI.isLowerThumbSelected() )
        {
            if (this.timeLineSliderUI.getLowerThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                lowerPressed = true;
            }
            else if (this.timeLineSliderUI.getUpperThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                upperPressed = true;
            } 
            else if (this.timeLineSliderUI.getThumbRect().contains(currentMouseX, currentMouseY))
        	{
            	currentPressed = true;
        	}
        }
        else
        {
            if (this.timeLineSliderUI.getThumbRect().contains(currentMouseX, currentMouseY))
        	{
            	currentPressed = true;
        	}
            else if (this.timeLineSliderUI.getLowerThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                lowerPressed = true;
            }
            else if (this.timeLineSliderUI.getUpperThumbRect().contains(currentMouseX, currentMouseY)) 
            {
                upperPressed = true;
            } 
        }

        // Handle lower thumb pressed.
        if (lowerPressed) {
            switch (this.timeLineSliderUI.getSlider().getOrientation()) {
            case JSlider.VERTICAL:
                offset = currentMouseY - this.timeLineSliderUI.getLowerThumbRect().y;
                break;
            case JSlider.HORIZONTAL:
                offset = currentMouseX - this.timeLineSliderUI.getLowerThumbRect().x;
                break;
            }
            this.timeLineSliderUI.setLowerThumbSelected(true);
            this.timeLineSliderUI.lowerDragging = true;
            return;
        }
        this.timeLineSliderUI.lowerDragging = false;
        
        // Handle upper thumb pressed.
        if (upperPressed) {
            switch (this.timeLineSliderUI.getSlider().getOrientation()) {
            case JSlider.VERTICAL:
                offset = currentMouseY - this.timeLineSliderUI.getUpperThumbRect().y;
                break;
            case JSlider.HORIZONTAL:
                offset = currentMouseX - this.timeLineSliderUI.getUpperThumbRect().x;
                break;
            }
            this.timeLineSliderUI.setUpperThumbSelected(true);
            this.timeLineSliderUI.upperDragging = true;
            return;
        }
        this.timeLineSliderUI.upperDragging = false;
        
        // Handle upper thumb pressed.
        if (currentPressed) {
            switch (this.timeLineSliderUI.getSlider().getOrientation()) {
            case JSlider.VERTICAL:
                offset = currentMouseY - this.timeLineSliderUI.getThumbRect().y;
                break;
            case JSlider.HORIZONTAL:
                offset = currentMouseX - this.timeLineSliderUI.getThumbRect().x;
                break;
            }
            this.timeLineSliderUI.currentDragging = true;
            return;
        }
        this.timeLineSliderUI.currentDragging = false;
    }
    
    @Override
    public void mouseReleased(MouseEvent e) {
        this.timeLineSliderUI.lowerDragging = false;
        this.timeLineSliderUI.upperDragging = false;
        this.timeLineSliderUI.currentDragging = false;
        this.timeLineSliderUI.getSlider().setValueIsAdjusting(false);
        super.mouseReleased(e);
    }
    
    @Override
    public void mouseDragged(MouseEvent e) {
        if (!this.timeLineSliderUI.getSlider().isEnabled()) {
            return;
        }

        currentMouseX = e.getX();
        currentMouseY = e.getY();

        if (this.timeLineSliderUI.lowerDragging) {
            this.timeLineSliderUI.getSlider().setValueIsAdjusting(true);
            moveLowerThumb();
        } else if (this.timeLineSliderUI.upperDragging) {
            this.timeLineSliderUI.getSlider().setValueIsAdjusting(true);
            moveUpperThumb();
        } else if (this.timeLineSliderUI.currentDragging) {
            this.timeLineSliderUI.getSlider().setValueIsAdjusting(true);
            moveCurrentThumb();
        }
    }
    
    public void moveCurrentThumb() {
    	  int thumbMiddle = 0;
          
          switch (this.timeLineSliderUI.getSlider().getOrientation()) {
              
          case JSlider.HORIZONTAL:
              int halfThumbWidth = this.timeLineSliderUI.getThumbRect().width / 2;
              int thumbLeft = currentMouseX - offset;
              int trackLeft = this.timeLineSliderUI.getTrackRect().x;
              int trackRight = this.timeLineSliderUI.getTrackRect().x + (this.timeLineSliderUI.getTrackRect().width - 1);
              int hMax = this.timeLineSliderUI.xPositionForValue(this.timeLineSliderUI.getSlider().getValue() + this.timeLineSliderUI.getSlider().getExtent());

              // Apply bounds to thumb position.
              if (this.timeLineSliderUI.drawInverted()) {
                  trackLeft = hMax;
              } else {
                  trackRight = hMax;
              }
              thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
              thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);

              this.timeLineSliderUI.setThumbLocation(thumbLeft, this.timeLineSliderUI.getThumbRect().y);

              thumbMiddle = thumbLeft + halfThumbWidth;
              this.timeLineSliderUI.getSlider().setValue(this.timeLineSliderUI.valueForXPosition(thumbMiddle));
              break;
              
          default:
              return;
          }		
	}

	@Override
    public boolean shouldScroll(int direction) {
        return false;
    }

    /**
     * Moves the location of the lower thumb, and sets its corresponding 
     * value in the slider.
     */
    private void moveLowerThumb() {
        int thumbMiddle = 0;
        
        switch (this.timeLineSliderUI.getSlider().getOrientation()) {
           case JSlider.HORIZONTAL:
            int halfThumbWidth = this.timeLineSliderUI.getLowerThumbRect().width / 2;
            int thumbLeft = currentMouseX - offset;
            int trackLeft = this.timeLineSliderUI.getTrackRect().x;
            int trackRight = this.timeLineSliderUI.getTrackRect().x + (this.timeLineSliderUI.getTrackRect().width - 1);
            int hMax = this.timeLineSliderUI.xPositionForValue(this.timeLineSliderUI.getSlider().getValue() + this.timeLineSliderUI.getSlider().getExtent());

            // Apply bounds to thumb position.
            if (this.timeLineSliderUI.drawInverted()) {
                trackLeft = hMax;
            } else {
                trackRight = hMax;
            }
            thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
            thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);


            thumbMiddle = thumbLeft + halfThumbWidth;
            
            
            
            if(this.timeLineSliderUI.valueForXPosition(thumbMiddle) <= this.timeLineSliderUI.timeLineSlider.upperValue)
            {
                this.timeLineSliderUI.setLowerThumbLocation(thumbLeft, this.timeLineSliderUI.getLowerThumbRect().y);
                this.timeLineSliderUI.timeLineSlider.setLowerValue(this.timeLineSliderUI.valueForXPosition(thumbMiddle));
            }
            else
            {
            	
            	this.timeLineSliderUI.setUpperThumbLocation(this.timeLineSliderUI.getUpperThumbRect().x, this.timeLineSliderUI.getUpperThumbRect().y);       	
            }
            
            break;
            
        default:
            return;
        }
    }

    /**
     * Moves the location of the upper thumb, and sets its corresponding 
     * value in the slider.
     */
    private void moveUpperThumb() {
        int thumbMiddle = 0;
        
        switch (this.timeLineSliderUI.getSlider().getOrientation()) {

        case JSlider.HORIZONTAL:
            int halfThumbWidth = this.timeLineSliderUI.getUpperThumbRect().width / 2;
            int thumbLeft = currentMouseX - offset;
            int trackLeft = this.timeLineSliderUI.getTrackRect().x;
            int trackRight = this.timeLineSliderUI.getTrackRect().x + (this.timeLineSliderUI.getTrackRect().width - 1);
            int hMin = this.timeLineSliderUI.xPositionForValue(this.timeLineSliderUI.getSlider().getValue());

            // Apply bounds to thumb position.
            if (this.timeLineSliderUI.drawInverted()) {
                trackRight = hMin;
            } else {
                trackLeft = hMin;
            }
            thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
            thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);
            

            thumbMiddle = thumbLeft + halfThumbWidth;
            
            if(this.timeLineSliderUI.valueForXPosition(thumbMiddle) >= this.timeLineSliderUI.timeLineSlider.lowerValue)
            {
            	this.timeLineSliderUI.setUpperThumbLocation(thumbLeft, this.timeLineSliderUI.getUpperThumbRect().y);
            	this.timeLineSliderUI.timeLineSlider.setUpperValue(this.timeLineSliderUI.valueForXPosition(thumbMiddle));
            }
            else
            {
            	
            	this.timeLineSliderUI.setUpperThumbLocation(this.timeLineSliderUI.getLowerThumbRect().x, this.timeLineSliderUI.getUpperThumbRect().y);       	
            }
            break;
            
        default:
            return;
        }
    }
}